/*
 * CommunicationDespacho.cpp
 *
 */

#include "CommunicationDespacho.h"

namespace middleware {

const std::string CommunicationDespacho::REQUEST_QUEUE_PATH = "/tmp/despacho";
const std::string CommunicationDespacho::REPLY_QUEUE_PATH  = "/tmp/despacho";
const std::string CommunicationDespacho::ENTREGA_QUEUE_PATH  = "/tmp/despacho";


CommunicationDespacho::CommunicationDespacho()
					:m_RequestQueue(ipc::MessageQueue<DespachoRequestStruct>::
						get(REQUEST_QUEUE_PATH,REQUEST_QUEUE_KEY)),
					m_ReplyQueue(ipc::MessageQueue<DespachoReplyStruct>::
						get(REPLY_QUEUE_PATH,REPLY_QUEUE_KEY)),
					m_EntregaQueue(ipc::MessageQueue<EntregaProductoStruct>::
						get(ENTREGA_QUEUE_PATH,ENTREGA_QUEUE_KEY))
{

}

CommunicationDespacho::~CommunicationDespacho() {
}

void CommunicationDespacho::getDespachoRequest(DespachoRequestType &reqType,
													OrdenCompraHeader &ordenCompra,
													ProductoCantidad &producto)

{
	DespachoRequestStruct request;
	request = m_RequestQueue.get(1);

	reqType = request.requestType;
	ordenCompra = request.ordenCompra;
	producto = request.producto;
}

void CommunicationDespacho::notificarDespachoOCLista(
		OrdenCompraHeader& ordenCompra, ProductoCantidad& producto)
{
	DespachoRequestStruct request;

	request.producto = producto;
	request.requestType = NOTIFICAR_DESPACHO;
	request.ordenCompra = ordenCompra;

	m_RequestQueue.put(1,request);
}

void CommunicationDespacho::esperarNotificacion(int clientId)
{
	DespachoReplyStruct reply;
	reply = m_ReplyQueue.get(clientId);

	if(reply.replyType != NOTIFICACION_CLIENTE)
		throw Exception("Notificacion de tipo incorrecto recibida");
}

void CommunicationDespacho::retirarProducto(OrdenCompraHeader& ordenCompra,
												  TipoProducto& tipoProducto,
												  Producto &producto)
{
	DespachoRequestStruct request;
	EntregaProductoStruct reply;

	request.producto.tipo = tipoProducto;
	request.requestType = RETIRAR;
	request.ordenCompra = ordenCompra;

	m_RequestQueue.put(1,request);
	reply = m_EntregaQueue.get(ordenCompra.clientId);

	producto = reply.producto;
}

void CommunicationDespacho::notificarCliente(OrdenCompraHeader &ordenCompra,
												   ProductoCantidad &producto)
{
	DespachoReplyStruct reply;

	reply.replyType = NOTIFICACION_CLIENTE;
	reply.producto = producto;
	reply.ordenCompra = ordenCompra;

	m_ReplyQueue.put(ordenCompra.clientId,reply);
}

void CommunicationDespacho::entregarProducto(OrdenCompraHeader& ordenCompra, Producto& producto)
{
	EntregaProductoStruct request;
	request.producto = producto;
	request.ordenCompra = ordenCompra;

	m_EntregaQueue.put(ordenCompra.clientId,request);
}

void CommunicationDespacho::create()
{
	ipc::MessageQueue<DespachoRequestStruct>::create(REQUEST_QUEUE_PATH,REQUEST_QUEUE_KEY);
	ipc::MessageQueue<DespachoReplyStruct>::create(REPLY_QUEUE_PATH,REPLY_QUEUE_KEY);
	ipc::MessageQueue<EntregaProductoStruct>::create(ENTREGA_QUEUE_PATH,ENTREGA_QUEUE_KEY);
}

void CommunicationDespacho::destroy()
{
	ipc::MessageQueue<DespachoRequestStruct>::destroy(REQUEST_QUEUE_PATH,REQUEST_QUEUE_KEY);
	ipc::MessageQueue<DespachoReplyStruct>::destroy(REPLY_QUEUE_PATH,REPLY_QUEUE_KEY);
	ipc::MessageQueue<EntregaProductoStruct>::destroy(ENTREGA_QUEUE_PATH,ENTREGA_QUEUE_KEY);
}

} /* namespace middleware */
